package com.dach.as.CheckDsk;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;


public class ChkDsk {

	private static boolean DEBUG = false;
	
	
	private static boolean handleInput( InputStream in, StringWriter sw ) throws IOException {
		
		BufferedReader br = new BufferedReader( new InputStreamReader( in ));
		
		String line;
		boolean error = false;
		boolean inConfig = false;
		while ( (line = br.readLine()) != null) {
			sw.append(line + "\n");
			
			if (error)
				continue;
			
			if (line.contains("state") && !line.contains("ONLINE"))
				error = true;
			
			if (line.contains("config:")) {
				inConfig = true;
				continue;
			}
			
			if (line.contains("errors:")) {
				inConfig=false;
				if (!line.contains("No known data errors"))
					error=true;
			}
				
			if (inConfig) {
				String[] lnEl = new String[] { "", "", "", "", "", "" };
				int i = -1;
				boolean b = false;
				for (int j=0; j<line.length();j++) {
					char c = line.charAt(j);
					if (c=='\t' || c==' ' || c=='\n') {
						b=true;
						continue;
					}
					
					if (b)
						i++;
					b=false;
					
					lnEl[i] += c;	
				}
				
				if (!lnEl[0].equals("") && !lnEl[0].equals("NAME")) {
					if (! (lnEl[1].equals("ONLINE") && lnEl[2].equals("0") && lnEl[3].equals("0") && lnEl[4].equals("0")) )
						error = true;
				}
			}
			
			
		}
		if (DEBUG)
			System.out.println("Query: \n" + sw.toString());
		
		return error;
	}
	
	
	
	
	private static void sendInformation( List<StringWriter> swList, boolean error) throws Exception {
		
		Properties p = new Properties();
		p.load( new FileInputStream("conf/chkdsk.conf"));
		
		String subject = "Scheduled Report about OpenSolaris Disks State";
		if (error)
			subject  = "ERROR in Open Solaris Disk State";
		
		System.out.println("Sending report to user " + p.getProperty("recipientsAddress") + ". Subject: " + subject);
		String text = "Chkdsk summary\n\n";
		
		for ( StringWriter sw : swList) 
			text += sw.toString() + "\n\n";
		
		if (DEBUG)
			Mail.DEBUG = true;
		
		Mail.sendMail(p.getProperty("smtp.host"), p.getProperty("smtp.user"), p.getProperty("smtp.pass"), p.getProperty("senderAddress"), p.getProperty("recipientsAddress"), subject, text, p.getProperty("smtp.auth", "false").equals("false")?false:true);
	}
	
	
	
	private static InputStream executeCommand( String pName ) throws Exception {
		Process p = Runtime.getRuntime().exec("zpool status " + pName);
		return p.getInputStream();
	}
	
	
	
	public static void main( String[] args) throws Exception {
		
		boolean report = false;
		boolean error = false;
		
		for (String s : args) {
			if (s.equals("-report"))
				report = true;
			if (s.equals("-debug"))
				DEBUG = true;
		}
		
		System.out.println("Running ChkDsk, mode: " + (report?"report":"regular testing"));
		if (DEBUG)
			System.out.println("Debug mode is enabled");
		
		StringWriter sw1 = new StringWriter();
		InputStream in1 = executeCommand("tank"); 
		boolean e1 = handleInput(in1, sw1);
		
		StringWriter sw2 = new StringWriter();
		InputStream in2 = executeCommand("rpool"); 
		boolean e2 = handleInput(in2, sw2);
		
		error = e1 || e2;
		
		List<StringWriter> swList = new ArrayList<StringWriter>();
		swList.add(sw1);
		swList.add(sw2);
		
		if (error) {
			System.out.println("Providing error report ...");
			sendInformation(swList, error);
		} else if (report) {
			System.out.println("Providing scheduled report ...");
			sendInformation(swList, error);
		} else
			System.out.println("No errors were detected, report option was not set (no notifications).");
	}
	
	
	
}
